package org.amphiprion.rfreplayanalyser.ui.lapanalyzer;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

import org.amphiprion.rfreplayanalyser.parser.Checkpoint;
import org.amphiprion.rfreplayanalyser.parser.Driver;
import org.amphiprion.rfreplayanalyser.parser.Replay;
import org.amphiprion.rfreplayanalyser.util.TimingUtil;

@SuppressWarnings("serial")
public class LapPickerDialog extends JDialog {
	private static final ResourceBundle BUNDLE = ResourceBundle.getBundle("org.amphiprion.rfreplayanalyser.ui.lapanalyzer.messages"); //$NON-NLS-1$
	private Replay replay;
	private final JPanel contentPanel = new JPanel();
	private JComboBox cbDrivers = new JComboBox();

	private JTable tblLaps;
	private List<LapItem> results = null;
	private List<float[]> sectors = new ArrayList<float[]>();

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		try {
			LapPickerDialog dialog = new LapPickerDialog(null);
			dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
			dialog.setVisible(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Create the dialog.
	 */
	public LapPickerDialog(Replay replay) {
		this.replay = replay;
		setTitle(BUNDLE.getString("LapPickerDialog.this.title")); //$NON-NLS-1$
		setBounds(100, 100, 450, 300);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		contentPanel.setLayout(new BorderLayout(0, 0));
		{
			JPanel panel = new JPanel();
			contentPanel.add(panel, BorderLayout.NORTH);
			panel.setLayout(new BorderLayout(0, 0));
			{
				JLabel lblNewLabel = new JLabel(BUNDLE.getString("LapPickerDialog.lblNewLabel.text")); //$NON-NLS-1$
				panel.add(lblNewLabel, BorderLayout.WEST);
			}
			{
				panel.add(cbDrivers, BorderLayout.CENTER);
			}
		}
		{
			JScrollPane scrollPane = new JScrollPane();
			contentPanel.add(scrollPane, BorderLayout.CENTER);
			{
				tblLaps = new JTable();
				scrollPane.setViewportView(tblLaps);
			}
		}
		{
			JPanel buttonPane = new JPanel();
			buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
			getContentPane().add(buttonPane, BorderLayout.SOUTH);
			{
				JButton okButton = new JButton("OK");
				okButton.addActionListener(new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent e) {
						if (cbDrivers.getSelectedIndex() != -1 && tblLaps.getSelectedRows().length > 0) {
							results = new ArrayList<LapItem>();
							for (int index : tblLaps.getSelectedRows()) {
								LapItem result = new LapItem(((Driver) cbDrivers.getSelectedItem()).getDriverId(), index);
								result.color = new Color((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255));
								result.laptime = sectors.get(result.lap)[0];
								result.sector1 = sectors.get(result.lap)[1];
								result.sector2 = sectors.get(result.lap)[2];
								result.sector3 = sectors.get(result.lap)[3];
								results.add(result);
							}
							setVisible(false);
						}
					}
				});
				okButton.setActionCommand("OK");
				buttonPane.add(okButton);
				getRootPane().setDefaultButton(okButton);
			}
			{
				JButton cancelButton = new JButton(BUNDLE.getString("LapPickerDialog.cancelButton.text")); //$NON-NLS-1$
				cancelButton.addActionListener(new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent arg0) {
						setVisible(false);
					}
				});
				cancelButton.setActionCommand("Cancel");
				buttonPane.add(cancelButton);
			}
		}
	}

	private void refreshTable(long driverId) {
		LapTableModel model = new LapTableModel();
		model.setColumnCount(5);

		float[] rowSector = new float[3];
		String[] row = new String[5];
		sectors.clear();
		int bestRow = -1;
		float best = 0;
		for (Checkpoint check : replay.getCheckpoints()) {

			if (check.getDriverId() == driverId) {
				if (check.getSectorReached() == 1) {
					rowSector[0] = check.getLaptime();
				} else if (check.getSectorReached() == 2) {
					rowSector[1] = check.getLaptime() - rowSector[0];
				} else if (check.getSectorReached() == 3) {
					rowSector[2] = check.getLaptime() - rowSector[1] - rowSector[0];
					row[0] = "" + check.getLap();
					row[1] = TimingUtil.getTimeAsLaptimeString(check.getLaptime());
					row[2] = TimingUtil.getTimeAsLaptimeString(rowSector[0]);
					row[3] = TimingUtil.getTimeAsLaptimeString(rowSector[1]);
					row[4] = TimingUtil.getTimeAsLaptimeString(rowSector[2]);

					if (check.getLaptime() > 0 && (bestRow == -1 || check.getLaptime() < best)) {
						best = check.getLaptime();
						bestRow = model.getRowCount();
					}
					sectors.add(new float[] { check.getLaptime(), rowSector[0], rowSector[1], rowSector[2] });
					model.addRow(row);
					row = new String[5];
				}

			}
		}
		model.setBestRow(bestRow);
		tblLaps.setDefaultRenderer(Object.class, new LapTableCellRenderer());
		tblLaps.setModel(model);
	}

	public static List<LapItem> show(Component parent, Replay replay) {
		final LapPickerDialog dlg = new LapPickerDialog(replay);
		dlg.setModal(true);
		dlg.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		dlg.cbDrivers.addItemListener(new ItemListener() {

			@Override
			public void itemStateChanged(ItemEvent arg0) {
				dlg.refreshTable(((Driver) arg0.getItem()).getDriverId());

			}
		});
		for (Driver driver : replay.getDrivers()) {
			dlg.cbDrivers.addItem(driver);
		}
		dlg.cbDrivers.setSelectedIndex(0);
		dlg.setLocationRelativeTo(parent);
		dlg.setVisible(true);
		return dlg.results;
	}

	class LapTableModel extends DefaultTableModel {

		String[] columns = { "Lap", "Laptime", "Sector 1", "Sector 2", "Sector 3" };
		int bestRow = -1;

		@Override
		public int getColumnCount() {
			return columns.length;
		}

		@Override
		public String getColumnName(int index) {
			return columns[index];
		}

		void setBestRow(int row) {
			this.bestRow = row;
		}

		boolean isBestRow(int row) {
			return row == bestRow;
		}

		@Override
		public boolean isCellEditable(int arg0, int arg1) {
			return false;
		}
	}

	static class LapTableCellRenderer extends DefaultTableCellRenderer {
		static Color bestColor = new Color(0, 122, 0);

		@Override
		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
			LapTableModel model = (LapTableModel) table.getModel();
			if (model.isBestRow(row) && column == 0) {
				value = value + " (best)";
			}
			Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
			if (model.isBestRow(row)) {
				c.setForeground(bestColor);
			} else {
				c.setForeground(Color.BLACK);
			}
			return c;
		}
	}
}
